package com.rockbb.common.utilities.text;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.ObjectMapper;

import com.rockbb.common.utilities.i18n.MessageResource;

public class ComponentBuilder {

	private static Logger logger = Logger.getLogger(ComponentBuilder.class);

	/**
	 * 生成一段链接HTML代码
	 * 
	 * @param langRes
	 * @param link
	 * @param text
	 * @param properties
	 * @return
	 */
	public static String buildHyperLink(MessageResource langRes, String link, String text, boolean target_blank)
	{
		StringBuffer sb = new StringBuffer();
		sb.append("<a ");
		if (link != null && link.length() > 0)
			sb.append("href=\""+link+"\" ");
		if (target_blank)
		{
			sb.append("target=\"_blank\" ");
		}
		if (langRes == null)
		{
			sb.append(">"+text+"</a>");
		}
		else
		{
			sb.append(">"+langRes.get(text)+"</a>");
		}
		return sb.toString();
	}

	/**
	 * 生成下拉菜单选项列表
	 * 
	 * @param langRes 当前会话的语言资源
	 * @param values 值 (为空时, 自动使用index值代替; 不为空时, 长度必须与names一致)
	 * @param names 显示条目名称
	 * @param selected 默认选中的项目
	 * @return HTML字符串
	 */
	public static String buildOptions(MessageResource langRes, List<String> values, List<String> names, int selected) 
	{
		String[] valueArray = values.toArray(new String[0]);
		String[] nameArray = names.toArray(new String[0]);
		return buildOptions(langRes, valueArray, nameArray, selected);
	}

	public static String buildOptions(MessageResource langRes, String[] values, String[] names, int selected) 
	{
		StringBuffer output = new StringBuffer();
		
		if(names==null) return "";
		
		if (values== null && names.length > 0)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = (i == selected)? " selected" : "";
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+i+"\""+extra+">"+name+"</option>\n");
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = (i == selected)? " selected" : "";
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+values[i]+"\""+extra+">"+name+"</option>\n");
			}
		}
 
		return output.toString();
	}

	public static String buildOptions(MessageResource langRes, List<String> values, List<String> names, String selected) 
	{
		String[] valueArray = values.toArray(new String[0]);
		String[] nameArray = names.toArray(new String[0]);
		return buildOptions(langRes, valueArray, nameArray, selected);
	}

	public static String buildOptions(MessageResource langRes, String[] values, String[] names, String selected) 
	{
		StringBuffer output = new StringBuffer();
		if (values == null)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = (selected != null && names[i].equals(selected))? " selected" : "";
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+i+"\""+extra+">"+name+"</option>\n");
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = (selected != null && values[i].equals(selected))? " selected" : "";
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+values[i]+"\""+extra+">"+name+"</option>\n");
			}
		}
		return output.toString();
	}

	public static String buildOptions(MessageResource langRes, List<String> values, List<String> names, List<String> selected_list) 
	{
		String[] value_array = values.toArray(new String[0]);
		String[] name_array = names.toArray(new String[0]);
		String[] selected_array = selected_list.toArray(new String[0]);
		return buildOptions(langRes, value_array, name_array, selected_array);
	}

	public static String buildOptions(MessageResource langRes, String[] values, String[] names, String[] selected_array) 
	{
		StringBuffer output = new StringBuffer();
		if (values == null)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = "";
				for (String selected : selected_array)
				{
					if (selected.equals(names[i])) {extra = " selected"; break;}
				}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+i+"\""+extra+">"+name+"</option>\n");
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = "";
				for (String selected : selected_array)
				{
					if (selected.equals(values[i])) {extra = " selected=\"selected\""; break;}
				}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<option title=\""+name+"\" value=\""+values[i]+"\""+extra+">"+name+"</option>\n");
			}
		}
		return output.toString();
	}

	public static String buildRadioButtons(MessageResource langRes, String box_name, String[] values, String[] names, String selected, String onClick)
	{
		StringBuffer output = new StringBuffer();
		if (values == null)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = "";
				if (selected.equals(names[i])) {extra = " checked=\"checked\"";}
				if (onClick != null && onClick.length() > 0) {extra += " onClick=\""+onClick+"\"";}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);

				output.append("\n<input type=\"radio\" class=\"radio\" name=\""+box_name+"\" id=\""+box_name+"_"+names[i]+"\" value=\""+names[i]+"\""+extra+" /> "+name);
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = "";
				if (selected.equals(values[i])) {extra = " checked=\"checked\"";}
				if (onClick != null && onClick.length() > 0) {extra += " onClick=\""+onClick+"\"";}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);

				output.append("\n<input type=\"radio\" class=\"radio\" name=\""+box_name+"\" id=\""+box_name+"_"+names[i]+"\" value=\""+values[i]+"\""+extra+" /> "+name);
			}
		}
		return output.toString();
	}
	
	public static String buildCheckBoxes(MessageResource langRes, String box_name, String[] values, String[] names, String[] selected_array) 
	{
		if (selected_array == null) selected_array = new String[]{};
		StringBuffer output = new StringBuffer();
		if (values == null)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = "";
				for (String selected : selected_array)
				{
					if (selected.equals(names[i])) {extra = " checked"; break;}
				}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);

				output.append("\n<dl><dt><label for=\""+box_name+"_"+names[i]+"\">"+name+"</label></dt>\n");
				output.append("<dd><input type=\"checkbox\" name=\""+box_name+"\" id=\""+box_name+"_"+names[i]+"\" value=\""+names[i]+"\""+extra+" /></dd></dl>");
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = "";
				for (String selected : selected_array)
				{
					if (selected.equals(values[i])) {extra = " checked"; break;}
				}
				String name = (langRes == null)? names[i] : langRes.get(names[i]);

				output.append("\n<dl><dt><label for=\""+box_name+"_"+names[i]+"\">"+name+"</label></dt>\n");
				output.append("<dd><input type=\"checkbox\" name=\""+box_name+"\" id=\""+box_name+"_"+names[i]+"\" value=\""+values[i]+"\""+extra+" /></dd></dl>");
			}
		}
		return output.toString();
	}

	public static String generate_pagination_dropdown(String base_url, String param, int num_items, int per_page,  int start_item, boolean add_prevnext_text, String tpl_prefix)
	{
		// Make sure per_page is a valid value
		per_page = (per_page <= 0) ? 10 : per_page;
		int total_pages = num_items / per_page +((num_items % per_page > 0)?1:0); // Instead of the ceil method

		int on_page = start_item / per_page + 1;
		String url_delim = (base_url.indexOf("?") > 0)? "&amp;" : "?";

		StringBuffer html_sb = new StringBuffer();
		html_sb.append("<span>");
		html_sb.append((on_page <= 1) ? "" : "<a href=\"" + base_url + url_delim + param + "=" + ((on_page - 2)*per_page) + "\">&lt;&lt;</a>");
		html_sb.append(" " + on_page + "/" + total_pages + " (" + num_items + ") ");
		html_sb.append((on_page == total_pages) ? "" : "<a href=\"" + base_url + url_delim + param+"=" + (on_page*per_page) + "\">&gt;&gt;</a>");
		if (total_pages > 3)
		{
			String js_bas_url = "'" + base_url + url_delim + param + "='";
			html_sb.append(" <select name=\"pagination_dropdown\" id=\"pagination_dropdown\" onchange=\"flip_page('pagination_dropdown', " + js_bas_url + ")\">");
			for (int i = 1; i <= total_pages; i ++)
			{
				html_sb.append("<option value=\"" + (i-1)*per_page + "\"" + ((i == on_page)?" selected": "") + ">" + i + "</option>");
			}
			html_sb.append("</select>");
		}

		return html_sb.toString();
	}
	
	/**
	* Pagination routine, generates page number sequence
	* tpl_prefix is for using different pagination blocks at one page
	*/
	public static String generate_pagination(String base_url, String param, long num_items, int per_page,  long start_item, boolean add_prevnext_text, String tpl_prefix) 
	{
		// Make sure per_page is a valid value
		per_page = (per_page <= 0) ? 1 : per_page;

		String seperator = " ";
		String current_pre = "<strong>";
		String current_pos = "</strong>";
		long total_pages = num_items / per_page +((num_items % per_page > 0)?1:0); // Instead of the ceil method

		if (total_pages == 1 || num_items == 0) {return "";}

		long on_page = start_item / per_page + 1;
		String url_delim = (base_url.indexOf("?") > 0)? "&amp;" : "?"; 

		StringBuffer page_string = new StringBuffer();
		page_string.append("<span>");
		page_string.append((on_page == 1) ? current_pre+"1"+current_pos : "<a href=\"" + base_url + "\">1</a>");

		if (total_pages > 5) {
			long start_cnt;
			if (on_page - 4 > 1) {start_cnt = on_page - 4;}
			else {start_cnt = 1;}
			if (total_pages - 5 < start_cnt) {start_cnt = total_pages - 5;}
			
			long end_cnt;
			if (on_page +4 > total_pages) {end_cnt = total_pages;}
			else {end_cnt = on_page + 4;}
			if (end_cnt < 6) {end_cnt = 6;}

			page_string.append((start_cnt > 1) ? " ... " : seperator);

			for (long i = start_cnt + 1; i < end_cnt; i++) {
				page_string.append((i == on_page) ? current_pre + i + current_pos : 
					"<a href=\"" + base_url + url_delim + param+"=" + ((i-1)*per_page) + "\">" + i + "</a>");
				if (i < end_cnt - 1) {
					page_string.append(seperator);
				}
			}
			page_string.append((end_cnt < total_pages) ? " ... " : seperator);

		} else {
			page_string.append(seperator);

			for (long i = 2; i < total_pages; i++) {
				page_string.append((i == on_page) ? current_pre + i + current_pos : 
					"<a href=\"" + base_url + url_delim + param+"=" + ((i-1)*per_page) + "\">" + i + "</a>");
				if (i < total_pages) {
					page_string.append(seperator);
				}
			}
		}

		page_string.append((on_page == total_pages) ? current_pre + total_pages + current_pos : 
			"<a href=\"" + base_url + url_delim + param+"=" + ((total_pages - 1) * per_page) + "\">" + total_pages + "</a>");

		if (add_prevnext_text) {
			if (on_page != 1) {
				page_string.append("<a href=\"" + base_url + url_delim + param+"=" + ((on_page - 2) * per_page) + "\">Previous</a>&nbsp;&nbsp;" + page_string);
			}

			if (on_page != total_pages) {
				page_string.append("&nbsp;&nbsp;<a href=\"" + base_url + url_delim + param+"=" + (on_page * per_page) + "\">Next</a>");
			}
		}
		page_string.append("</span>");

		return page_string.toString();
	}

	public static List<Map<String, List<String>>> extractRules(String rulestring) {
		List<Map<String, List<String>>> rules = new ArrayList<Map<String, List<String>>>();
		if (rulestring == null) return rules;

		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			rules = mapper.readValue(rulestring, rules.getClass());
		} catch (JsonParseException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return rules;
	}

	public static String compressRules(List<Map<String, List<String>>> rules) {
		String rulestring = "";
		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			rulestring = mapper.writeValueAsString(rules);
		} catch (JsonGenerationException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return rulestring;
	}

	public static Map<String, List<String>> extractRulesMap(String rulestring) {
		Map<String, List<String>> rules = new HashMap<String, List<String>>();
		if (rulestring == null || rulestring.length() == 0) return rules;

		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			rules = mapper.readValue(rulestring, rules.getClass());
		} catch (JsonParseException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return rules;
	}

	public static String compressRulesMap(Map<String, List<String>> rules) {
		String rulestring = "";
		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			rulestring = mapper.writeValueAsString(rules);
		} catch (JsonGenerationException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return rulestring;
	}

	public static Map<String, Object> extractParameters(String paramstring) {
		Map<String, Object> parameters = new HashMap<String, Object>();
		if (paramstring == null) return parameters;

		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			parameters = mapper.readValue(paramstring, parameters.getClass());
		} catch (JsonParseException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return parameters;
	}

	public static String compressParameters(Map<String, Object> parameters) {
		String paramstring = "";
		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			paramstring = mapper.writeValueAsString(parameters);
		} catch (JsonGenerationException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return paramstring;
	}

	public static List<String> extractStringList(String listString) {
		List<String> list = new ArrayList<String>();
		if (listString == null) return list;

		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			list = mapper.readValue(listString, list.getClass());
		} catch (JsonParseException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return list;
	}

	public static String compressStringList(List<String> list) {
		String listString = "";
		ObjectMapper mapper = JacksonMapper.getInstance();
		try {
			listString = mapper.writeValueAsString(list);
		} catch (JsonGenerationException e) {
			// Do nothing
		} catch (IOException e) {
			// Do nothing
		}
		return listString;
	}

	/**
	 * @param langRes 
	 * @param values radio的value
	 * @param names radio的显示的文字
	 * @param prefix 被控制的div的前缀
	 * @param divname 被控制div的名称
	 * @param selected 被选择的div编码，和value值对应
	 * @return
	 */
	public static String buildRadios(MessageResource langRes, String[] values, String[] names, String prefix, String divname, int selected)
	{
		StringBuffer output = new StringBuffer();
		if (values == null)
		{
			for (int i=0; i<names.length; i++) 
			{
				String extra = "";
				if ((selected+"").equals(names[i])) {extra = " checked"; }
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<input type=\"radio\" class=\"radio\" value=\""+name+"\" name=\""+divname+prefix+"\" "+extra+" onclick=\"changeSelected('"+prefix+"','"+divname+"',this);\"> "+name+"\t");
			}
		}
		else if (values.length == names.length) 
		{
			for (int i=0; i<values.length; i++) 
			{
				String extra = "";
				if ((selected+"").equals(values[i])) {extra = " checked"; }
				String name = (langRes == null)? names[i] : langRes.get(names[i]);
				output.append("<input type=\"radio\" class=\"radio\" value=\""+values[i]+"\" name=\""+divname+prefix+"\" "+extra+" onclick=\"changeSelected('"+prefix+"','"+divname+"',this);\"> "+name+"\t");
			}
		}
		return output.toString();
	}
	/**
	 * Test cases
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		List<Map<String, List<String>>> rules = new ArrayList<Map<String, List<String>>>();
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		List<String> aa = new ArrayList<String>();
		aa.add("aa");aa.add("aa");aa.add("aa");
		map.put("aa", aa);
		aa = new ArrayList<String>();
		aa.add("bb");aa.add("bb");aa.add("bb");
		map.put("bb", aa);
		aa = new ArrayList<String>();
		aa.add("cc");aa.add("cc");aa.add("cc");
		map.put("cc", aa);
		rules.add(map);
		map = new HashMap<String, List<String>>();
		aa = new ArrayList<String>();
		aa.add("11");aa.add("11");aa.add("11");
		map.put("11", aa);
		aa = new ArrayList<String>();
		aa.add("22");aa.add("22");aa.add("22");
		map.put("22", aa);
		aa = new ArrayList<String>();
		aa.add("33");aa.add("33");aa.add("33");
		map.put("33", aa);
		rules.add(map);
		String str = compressRules(rules);
		System.out.println(str);
		List<Map<String, List<String>>> recovered = extractRules(str);
		for (Map<String, List<String>> newMap : recovered) {
			Iterator<String> it = newMap.keySet().iterator();
			while(it.hasNext())
			{
				// 或链
				String key = it.next();
				List<String> tags = newMap.get(key);
				for (String tag : tags)
					System.out.println(tag);
			}
		}
		
		
		String out = generate_pagination("a.html", "start", 100, 10, 0, false, null);
		System.out.println(out);
	}

}
